package com.learn.motion.demo.dissolve

import android.animation.Animator
import android.animation.ObjectAnimator
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.view.ViewGroup
import android.view.ViewOverlay
import androidx.core.animation.doOnEnd
import androidx.core.view.drawToBitmap
import androidx.transition.Transition
import androidx.transition.TransitionValues

class Dissolve : Transition() {
    companion object {
        private const val PROPNAME_BITMAP = "com.learn.motion.demo.dissolve:bitmap"

        /**
         * 此过渡依赖于 [ViewOverlay] 来显示动画。在不支持它的旧设备上，此转换不会执行任何操作
         */
        private val SUPPORT_VIEW_OVERLAY = Build.VERSION.SDK_INT >= 18
    }

    override fun captureStartValues(transitionValues: TransitionValues) {
        captureValues(transitionValues)
    }

    override fun captureEndValues(transitionValues: TransitionValues) {
        captureValues(transitionValues)
    }

    private fun captureValues(transitionValues: TransitionValues) {
        if (SUPPORT_VIEW_OVERLAY) {
            transitionValues.values[PROPNAME_BITMAP] = transitionValues.view.drawToBitmap()
        }
    }

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {
        if (startValues == null || endValues == null || !SUPPORT_VIEW_OVERLAY) {
            return null
        }
        val startBitmap = startValues.values[PROPNAME_BITMAP] as Bitmap
        val endBitmap = endValues.values[PROPNAME_BITMAP] as Bitmap

        // 如果startBitmap和endBitmap看起来一样就不需要动画处理
        if (startBitmap.sameAs(endBitmap)) {
            return null
        }
        val view = endValues.view
        val startDrawable = BitmapDrawable(view.resources, startBitmap).apply {
            setBounds(0, 0, startBitmap.width, startBitmap.height)
        }

        val overlay = view.overlay
        overlay.add(startDrawable)

        return ObjectAnimator.ofInt(startDrawable, "alpha", 255, 0).apply {
            doOnEnd {
                overlay.remove(startDrawable)
            }
        }
    }
}